﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "PropertyPaletteEventHandler.h"
#include "PropertyPalette.h"
#include "IUserTransaction.h"
#include "IPropertyPanelEvent.h"
#include "IPropertyPanelEventArgs.h"
#include "IParameter.h"
#include "IElementParameters.h"
#include "IUiDocument.h"
#include "IUiDocumentViewManager.h"
#include "IParameterDefinitionLibrary.h"
#include "ByCategoryOrSetMaterialDialog.h"
#include "IGraphicsMaterial.h"
#include "IFamilyManager.h"
#include "UiCommonDialog.h"
#include "StringUtil.h"
#include "GcmpBuiltInParameterDefinitions.h"
#include "IElementBasicInformation.h"
#include "IGraphicsStyleManager.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;

//////////////////////////////////////////////////////////////////////////
IMPLEMENT_UI_EVENT_HANDLER(PropertyPaletteEventHandler);

PropertyPaletteEventHandler::PropertyPaletteEventHandler() 
{
}

PropertyPaletteEventHandler::~PropertyPaletteEventHandler()
{
    UI_EVENT_HANDLER_SHOULD_CALL_ME_FIRSTLY_IN_DESTRUCTOR();
}

void PropertyPaletteEventHandler::Register()
{
    if (PropertyPalette* pPropertyPalette = PropertyPalette::GetPropertyPalette())
    {
        pPropertyPalette->GetInputEvent()->Add(this);
    }
}

//////////////////////////////////////////////////////////////////////////
void PropertyPaletteEventHandler::On(IPropertyPanelEventArgs* pArgs)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pArgs, L"pArgs为空",L"GDMPLab",L"2024-03-30");
    if (pArgs->GetType() == L"PropertyItemButtonClicked")
    {
        PropertyPalette* pPropertyPalette = PropertyPalette::GetPropertyPalette();
        if (!pPropertyPalette)
            return;

        std::vector<ElementId> selElements;
        pPropertyPalette->GetShowElements(selElements);
        if (selElements.empty())
            return;

        IUiDocument* pUIDoc = IUiDocumentViewManager::Get()->GetCurrentUiDocument();
        if (pUIDoc == nullptr)
        {
            return ;
        }
        gcmp::IDocument* pDocument = pUIDoc->GetDbDocument();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pDocument, L"pDocument为空",L"GDMPLab",L"2024-03-30");

        const IParameterDefinitionLibrary* pParamDefLib = IParameterDefinitionLibrary::Get(pDocument);
        DBG_WARN_AND_RETURN_VOID_UNLESS(pParamDefLib != nullptr, L"pParamDefLib为空",L"GDMPLab",L"2024-03-30");
        int paramId = pParamDefLib->GetParameterDefinitionIdByUid(PARAMETER_UID(FormMaterialBuiltInParameter));
        int uniquiID = StringUtil::ToNumber<int>(pArgs->GetPropertyItemUniqueId());

        if (uniquiID == paramId)
        {
            // 得到选中的材质
            ByCategoryOrSetMaterialDialog inquiryDialog;
            if (inquiryDialog.exec() != QDialog::Accepted)
                return;

            if (inquiryDialog.IsToByCategory())
            {
                if (pPropertyPalette->m_upUserTransaction == nullptr)
                {
                    pPropertyPalette->m_upUserTransaction = IUserTransaction::Create(pDocument, GBMP_TR(L"修改构件属性"));
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pPropertyPalette->m_upUserTransaction != nullptr, L"pPropertyPalette->m_upUserTransaction为空",L"GDMPLab",L"2024-03-30");
                }
                if (!pPropertyPalette->m_upUserTransaction->IsStarted())
                {
                    pPropertyPalette->m_upUserTransaction->Start();
                }
                IGraphicsStyleManager* pGraphicsStyleManager = pDocument->GetGraphicsStyleManager();
                DBG_WARN_AND_RETURN_VOID_UNLESS(pGraphicsStyleManager != nullptr, L"pGraphicsStyleManager为空",L"GDMPLab",L"2024-03-30");
                UniIdentity categoryUid = gfam::IFamilyManager::Get(pDocument)->GetBasicInformation()->GetCategoryUid();
                ElementId materialId = pGraphicsStyleManager->GetGraphicsStyleIdByCategoryUid(categoryUid);
                IGraphicsMaterial *pMaterial = quick_cast<IGraphicsMaterial>(pDocument->GetElement(materialId));
                DBG_WARN_UNLESS(pMaterial != nullptr, L"没有找到IGraphicsMaterial对象",L"GDMPLab",L"2024-03-30");
                // pMaterial->SetUpdated();

                for (int i = 0; i < (int)selElements.size(); ++i)
                {
                    IElement* pSelectedElement = pDocument->GetElement(selElements[i]);
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pSelectedElement != nullptr, L"pSelectedElement为空",L"GDMPLab",L"2024-03-30");

                    OwnerPtr<IParameter> curParam;
                    if (pSelectedElement->GetElementParameters())
                    {
                        curParam = pSelectedElement->GetElementParameters()->GetParameterById(uniquiID);
                        curParam->SetValueAsElementId(materialId);
                        pSelectedElement->GetElementParameters()->SetParameter(curParam.get());
                    }
                }
                pPropertyPalette->m_bTransactionIsCommitting = true;
                pPropertyPalette->m_upUserTransaction->Commit();
                pPropertyPalette->m_bTransactionIsCommitting = false;
            }
            else if (inquiryDialog.IsToSetMaterial())
            {
                ElementId materialId;
                UiCommonDialog::ButtonType res = UiCommonDialog::ShowMaterialSelectionDialog(pUIDoc->GetDbDocument(), materialId);
                if (res != UiCommonDialog::ButtonType::OK || !materialId.IsValid())
                {
                    return;
                }

                if (pPropertyPalette->m_upUserTransaction == nullptr)
                {
                    pPropertyPalette->m_upUserTransaction = IUserTransaction::Create(pDocument, GBMP_TR(L"修改构件属性"));
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pPropertyPalette->m_upUserTransaction != nullptr, L"pPropertyPalette->m_upUserTransaction为空",L"GDMPLab",L"2024-03-30");
                }
                if (!pPropertyPalette->m_upUserTransaction->IsStarted())
                {
                    pPropertyPalette->m_upUserTransaction->Start();
                }

                IGraphicsMaterial *pMaterial = quick_cast<IGraphicsMaterial>(pDocument->GetElement(materialId));
                if (pMaterial != nullptr)
                {
                    //pMaterial->SetUpdated();
                    for (int i = 0; i < (int)selElements.size(); ++i)
                    {
                        IElement* pSelectedElement = pDocument->GetElement(selElements[i]);
                        DBG_WARN_AND_RETURN_VOID_UNLESS(pSelectedElement != nullptr, L"pSelectedElement为空",L"GDMPLab",L"2024-03-30");

                        OwnerPtr<IParameter> curParam;
                        if (pSelectedElement->GetElementParameters())
                        {
                            curParam = pSelectedElement->GetElementParameters()->GetParameterById(uniquiID);
                            curParam->SetValueAsElementId(materialId);
                            pSelectedElement->GetElementParameters()->SetParameter(curParam.get());
                        }
                    }
                    pPropertyPalette->m_bTransactionIsCommitting = true;
                    pPropertyPalette->m_upUserTransaction->Commit();
                    pPropertyPalette->m_bTransactionIsCommitting = false;
                }
                else
                {
                    pPropertyPalette->m_upUserTransaction->Rollback();
                }
            }
        }

        pPropertyPalette->Refresh(false);
    }
}